﻿using ArtMath.Attribute;
using ArtMath.Component.Interface;
using ArtMath.Component.Manager;
using ArtMath.Component.Point;
using ArtMath.Core.Helper;
using ArtMath.Data;
using System;
using System.ComponentModel;
using System.Linq;

namespace ArtMath.Component.Line
{
    /// <summary>
    /// 切线
    /// </summary>
    [Serializable]
    public class TangentLine : PointSlopeLineBase
    {
        LineBase curve;
        ICurveLike curInfo;
        TangentLinesManagerBase mgr;
        //public double? CalculatedSlope;
        public TangentLine(SketchPad pad, string name, LineBase cur, TangentLinesManagerBase mgr = null, bool addToList = true) : base(pad, name, ToolTypeName.qx, addToList)
        {
            this.mgr = mgr;
            InPoints = new PointBase[1];
            Curve = cur;
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("Curve"), TypeConverter(typeof(ExpandableObjectConverter))]
        public LineBase Curve
        {
            get { return curve; }
            set
            {
                if (curve != null)
                {
                    curInfo = null;
                    curve.OutChildren_Line.Remove(this);
                }
                curve = value;
                if (curve != null)
                {
                    curInfo = curve as ICurveLike;
                    curve.OutChildren_Line.Add(this);
                }
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("TangentPoint")]
        public PointBase TangentPoint
        {
            get { return InPoints[0]; }
            set { SetPoint(0, value); }
        }
        public override double NewSlope
        {
            get
            {
                TangentLinesManager_A ta = mgr as TangentLinesManager_A;
                if (ta != null)
                {
                    if (ta.NewSlopes.TryGetValue(this, out double res))
                    {
                        return res;
                    }
                }
                double? k = curInfo.GetTangentLineSlope(TangentPoint.NewXY);
                if (k.HasValue)
                {
                    return k.Value;
                }
                return base.NewSlope;
            }
        }
        [Browsable(false)]
        public override AngleStringX RotateAngle
        {
            get
            {
                return base.RotateAngle;
            }

            set
            {
                base.RotateAngle = value;
            }
        }
        [Browsable(false)]
        public override RPointS RotateCenter
        {
            get
            {
                return base.RotateCenter;
            }

            set
            {
                base.RotateCenter = value;
            }
        }
        public override double NewPSlope
        {
            get
            {
                return Pad.kToPk(NewSlope);
            }
        }
        public override string Name
        {
            get
            {
                return base.Name;
            }

            set
            {
                TangentLinesManager_A ta = mgr as TangentLinesManager_A;
                if (ta != null)
                {
                    if (!string.IsNullOrEmpty(value))
                    {
                        if (ta.CheckLineNameExist(value))
                        {
                            value = Utility.GetNextAvailableName(value, ta.CheckLineNameExist);
                        }
                    }
                }
                base.Name = value;
            }
        }
        public override ComponentManagerBase ComponentManager
        {
            get
            {
                return mgr;
            }
        }
        public override void CreateComponents()
        {
            if (TangentPoint == null)
            {
                TangentPoint = Pad.CreatePoint(Curve.OfTranslator("TangentPoint"), SpareCoordinate_);
                if (mgr is TangentLinesManager_A)
                {

                }
                else
                {
                    double? k = curInfo.GetTangentLineSlope(TangentPoint.ToPointD());
                    if (k.HasValue)
                    {
                        Slope = k.Value;
                    }
                }
                base.CreateComponents();
            }
        }
        public override PointBase GetCommonPoint(StraightLineBase line)
        {
            if (mgr.Lines.Contains(line))
            {
                return mgr.PassPoint;
            }
            return base.GetCommonPoint(line);
        }
        public override void Delete(bool recoverable = false)
        {
            base.Delete(recoverable);
            if (!recoverable)
            {
                Curve = null;
            }
        }
        //public override void ComponentChanged(ShapeBase component)
        //{
        //    CalculatedSlope = null;
        //    base.ComponentChanged(component);
        //}
    }
}
